Demo: Aligning Numbers

by Bill Jennings

bbjen@hotPOP.com


Home

Index

Editor's Note:

Around mid-November in the Liberty BASIC discussion group at the Conforums site, there was a discussion about the best way to align numbers within various types of controls. Many participants agreed that the best way was to use a fixed-width font in a Liberty BASIC TEXTBOX or TEXTEDITOR control. Bill Jennings wrote the following demo to show that non-fixed-width fonts can be aligned quite nicely.

Thanks, Bill!


Screenshot: Decimal alignment shown



'   alignNumbers.bas

'   Align with non-fixed font in a
'     textbox, texteditor, or graphicbox
'     by the numbers' left end, right end,
'     or decimal point.
'     Bill Jennings,  November 2003

     nomainwin

    wTb=200  'width of textbox
    wTe=314  'width of texteditor
    wGb=314  'width of graphicbox

    WindowWidth=640 : WindowHeight=480
    statictext #w1.st1, "Textbox -->",136,6,60,16
    statictext #w1.st2a, "Texteditor",80,30,200,16
    statictext #w1.st2b, "Graphicbox",440,30,200,16
    statictext #w1.st3, "Align:",40,394,40,24
    button #w1.b1, "left",[left],UL,80,390
    button #w1.b2, "right",[right],UL,155,390
    button #w1.b3, "decimal",[decimal],UL,240,390
    button #w1.b4, "quit",[quit],UL,360,390
    textbox #w1.tb1, 200,0,wTb,30
    texteditor #w1.te1, 1,46,wTe,340
    graphicbox #w1.g1, 318,46,wGb,340
      open "" for window as #w1
      print #w1, "trapclose [quit]"
      print #w1.g1, "down"
      fontSize=18
      print #w1.g1, "font Arial 0 ";fontSize
      print #w1.tb1, "!font Arial 0 ";fontSize
      print #w1.te1, "!font Arial 0 ";fontSize

    gosub [getNumbers]
    gosub [getStringwidths]
    goto [left]  'Show left alignment to start.

[quit]
    close #w1
  END

[left]
    'left alignment is automatic in the textbox:
    print #w1.tb1, ""  'clear textbox
    numTxtBox=int(rnd(1)*16)+1  'random index --
      'use it for [right] & [decimal] modules
    print #w1.tb1, n$(numTxtBox)

    'and the texteditor:
    print #w1.te1, "!cls"  'clear texteditor
    for j=1 to nNum
      print #w1.te1, n$(j)
    next j

    'as well as the graphicbox:
    gosub [initGraphicbox]
    for j=1 to nNum
      print #w1.g1, "\";n$(j)
    next j
  WAIT

[right]
    'textbox:
    print #w1.tb1, ""  'clear textbox
    a$=n$(numTxtBox) : wA=wNum(numTxtBox)
    'accumulate spaces to make a left margin
    cor1=-16  '*** see Note 1 at end of code
    cor2=int(wA/40)  '*** see Note 2 at end of code
    while wA < wTb+cor1+cor2
      a$=" "+a$
      wA=width(a$)  'See Function at end of code
    wend
    print #w1.tb1, a$

    'texteditor:
    print #w1.te1, "!cls"  'clear texteditor
    for j=1 to nNum
      a$=n$(j) : wA=wNum(j)
      'accumulate spaces to make a left margin
      cor1=-23  '*** see Note 1 at end of code
      cor2=int(wA/40)  '*** see Note 2 at end of code
      while wA < wTe+cor1+cor2
        a$=" "+a$
        wA=width(a$)  'See Function at end of code
      wend
      print #w1.te1, a$
    next j

    'graphicbox:
    gosub [initGraphicbox]
    for j=1 to nNum
      wA=wNum(j) : xPos=wGb-wA-4  'horizontal position
      yPos=j*fontSize  'vertical position
      print #w1.g1, "place ";xPos;" ";yPos
      print #w1.g1, "\";n$(j)
    next j
  WAIT

[decimal]
    'textbox:
    print #w1.tb1, ""  'clear textbox
    decPos=int(wTb/2)  'position decimal point
    a$=n$(numTxtBox)
    p=instr(a$,".")
    lf$=left$(a$,p) : rt$=mid$(a$,p+1)
    wL=wLf(numTxtBox)
    'accumulate spaces to make a left margin
    cor1=-16  '*** see Note 1 at end of code
    cor2=int(wL/40)  '*** see Note 2 at end of code
    while wL < decPos+cor1+cor2
      lf$=" "+lf$
      wL=width(lf$)  'See Function at end of code
    wend
    print #w1.tb1, lf$+rt$

    'texteditor:
    print #w1.te1, "!cls"  'clear texteditor
    decPos=int(wGb/2)  'position decimal point
    for j=1 to nNum
      p=instr(n$(j),".")
      lf$=left$(n$(j),p) : rt$=mid$(n$(j),p+1)
      wL=wLf(j)
      'accumulate spaces to make a left margin
      cor1=-23  '*** see Note 1 at end of code
      cor2=int(wL/40)  '*** see Note 2 at end of code
      while wL < decPos+cor1+cor2
        lf$=" "+lf$
        wL=width(lf$)  'See Function at end of code
      wend
      print #w1.te1, lf$+rt$
    next j

    'graphicbox:
    gosub [initGraphicbox]
    decPos=int(wGb/2)  'position decimal point
    for j=1 to nNum
      wL=wLf(j)
      xPos=decPos-wL
      yPos=j*fontSize  'vertical position
      print #w1.g1, "place ";xPos;" ";yPos
      print #w1.g1, "\";n$(j)
    next j
  WAIT

[initGraphicbox]
      print #w1.g1, "fill 207 248 226"
      print #w1.g1, "backcolor 207 248 226"
      print #w1.g1, "color darkpink"
      print #w1.g1, "down; place 1 18"
  RETURN

[getNumbers]  'Make an assortment of random numbers.
    'If a number is an integer or zero,
    '  tack on a decimal point.
    nNum=16
    DIM n$(nNum)
    for j=1 to nNum
      mul=3^j
      n=int(rnd(1)*mul+1)/14
      Select Case n
        Case int(n)  'n is an integer
          ntg=1  'flag integer
          n$(j)=str$(n)+"."
        Case 0  'n is zero
          n$(j)=str$(n)+".0"
        Case Else
          n$(j)=str$(n)
      End Select
    next j

    'If no integer in the group, create one.
    if not(ntg) then
      for j=1 to nNum
        if val(n$(j)) > 0 then
          n$(j)=str$(int(val(n$(j))))+"."
          j=29
        end if
      next j
    end if
  RETURN

[getStringwidths]
    DIM wNum(nNum)  'entire width (pixels)
    DIM wLf(nNum)  'width left of decimal

    for j=1 to nNum
      wNum(j)=width(n$(j))  'See Function below.
      p=instr(n$(j),".")  'find decimal position
      wLf(j)=width(left$(n$(j),p-1))  'width of
        'left side of number string
    next j
  RETURN

  Function width(aString$)  'See 'stringwidth?'
    'command in the LB3 helpfile.
    print #w1.g1, "stringwidth? aString$ width"
  End Function

'NOTES:
  '*** Note 1 (does not apply to graphicbox):
'  cor1 is a correction factor for justification
'  that must be determined by trial and error.
'  It is different for various fonts and sizes, and
'  depends on the width of the textbox or texteditor.
'  Some other values for cor1:
'    fontSize   cor1
'       10      274
'       12       80
'       16      -20
'       24     -120
'       36     -184

  '*** Note 2 (does not apply to graphicbox):
'  cor2 is a correction factor for the length of
'  the number string.  It also must be determined
'  by trial and error.

  '*** Additional notes:
'  I tried to derive an equation for the
'  correction for various font sizes, but
'  my results were only approximate and
'  unsatisfactory.

'  ALIGNMENT IN GRAPHICS IS STRAIGHTFORWARD
'  (REQUIRES NO CORRECTIONS)!



Home

TCP/IP Tutorial

Rich Text Format Help

Creating Graphics for Games

Automatic Menu

Humble CAD Viewer

Demo: Aligning Numbers

Thoughts On Cross-Platform Help

Submission Guildlines

Newsletter Help

Index